<?php
/**
 * This file is part of Hyperf Mall.
 *
 * @link     https://gitee.com/scwlkj/hyperf_mall
 * @contact  hyperf_mall@163.com
 */

declare(strict_types=1);

namespace App\Command;

use Hyperf\Command\Command as HyperfCommand;
use Hyperf\Command\Annotation\Command;
use Hyperf\Database\Schema\Schema;
use Psr\Container\ContainerInterface;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Output\StreamOutput;

/**
 * @Command
 */
#[Command]
class LazyCommand extends HyperfCommand
{
    /**
     * @var ContainerInterface
     */
    protected $container;

    /**
     * @var string
     */
    protected $pre;

    /**
     * @var array
     */
    protected $names;

    public function __construct(ContainerInterface $container)
    {
        $this->container = $container;

        parent::__construct('lazy:get');
    }

    public function configure()
    {
        parent::configure();
        $this->addArgument('name',InputArgument::OPTIONAL,'表名','member_point');
        $this->setDescription('懒人一键生成代码命令');
    }

    public function handle()
    {
        $this->line('代码生成中...', 'info');
        $name =  $this->input->getArgument('name');

        $this->makeName($name);

        $this->makeInterface();
        $this->makeService();
        $this->makeRepository();
        $this->makeModel();
    }

    private function makeName($name)
    {
        $pre = ucfirst(preg_replace_callback('/_([A-Za-z])/',function ($matches){
            return strtoupper($matches[1]);
        },$name));

        $columns = Schema::getColumnListing($name);
        $columns = array_diff($columns, ['id','delete_time']);

        $this->names = [
            'filltable'=>$columns,
            'service_name'=>$pre . 'Service',
            'interface_name'=>$pre . 'ServiceInterface',
            'repository_name'=>$pre . 'Repository',
            'model_name'=>$pre . 'Model',
            'service_path'=>BASE_PATH . "/app/JsonRpc/".$pre . "Service.php",
            'interface_path'=>BASE_PATH . "/app/JsonRpc/Interfaces/".$pre . "ServiceInterface.php",
            'repository_path'=>BASE_PATH . "/app/Repository/".$pre . "Repository.php",
            'model_path'=>BASE_PATH . "/app/Model/".$pre . "Model.php",
            'service'=> env("APP_NAME") ? (ucfirst(env("APP_NAME")) . '::'. $pre . 'Service') : $pre . 'Service'
        ];
    }

    private function makeService()
    {
        $output = new StreamOutput(fopen($this->names['service_path'], 'w+', false));
        $output->writeln("<?php");
        $output->writeln("/**");
        $output->writeln(" * This file is part of Hyperf Mall.");
        $output->writeln(" * ");
        $output->writeln(" * @link     https://gitee.com/scwlkj/hyperf_mall");
        $output->writeln(" * @contact  hyperf_mall@163.com");
        $output->writeln(" */");
        $output->writeln("");
        $output->writeln("declare(strict_types=1);");
        $output->writeln("");
        $output->writeln("namespace App\JsonRpc;");
        $output->writeln("");
        $output->writeln("use App\\Repository\\".$this->names['repository_name'].";");
        $output->writeln("use Hyperf\\RpcServer\\Annotation\\RpcService;");
        $output->writeln("use App\\JsonRpc\\Interfaces\\".$this->names['interface_name'] . ";");
        $output->writeln("");

        $output->writeln("/**");
        $output->writeln(" * @RpcService(name=\"".$this->names['service']."\", protocol=\"jsonrpc\", server=\"jsonrpc\")");
        $output->writeln(" */");

        $output->writeln("class ".$this->names['service_name']." extends BaseService implements ". $this->names['interface_name']);
        $output->writeln("{");
        $output->writeln("    public function init()");
        $output->writeln("    {");
        $output->writeln("        \$this->repository = ".$this->names['repository_name']."::getInstance();");
        $output->writeln("    }");
        $output->writeln("}");

        $this->line($this->names['service_path'] . "已生成", 'info');
    }

    private function makeInterface()
    {
        $output = new StreamOutput(fopen($this->names['interface_path'], 'w+', false));
        $output->writeln("<?php");
        $output->writeln("/**");
        $output->writeln(" * This file is part of Hyperf Mall.");
        $output->writeln(" * ");
        $output->writeln(" * @link     https://gitee.com/scwlkj/hyperf_mall");
        $output->writeln(" * @contact  hyperf_mall@163.com");
        $output->writeln(" */");
        $output->writeln("");
        $output->writeln("declare(strict_types=1);");
        $output->writeln("");
        $output->writeln("namespace App\JsonRpc\Interfaces;");
        $output->writeln("");
        $output->writeln("interface ".$this->names['interface_name']."{}");

        $this->line($this->names['interface_path'] . "已生成", 'info');
    }

    private function makeRepository()
    {
        $output = new StreamOutput(fopen($this->names['repository_path'], 'w+', false));
        $output->writeln("<?php");
        $output->writeln("/**");
        $output->writeln(" * This file is part of Hyperf Mall.");
        $output->writeln(" * ");
        $output->writeln(" * @link     https://gitee.com/scwlkj/hyperf_mall");
        $output->writeln(" * @contact  hyperf_mall@163.com");
        $output->writeln(" */");
        $output->writeln("");
        $output->writeln("declare(strict_types=1);");
        $output->writeln("");
        $output->writeln("namespace App\Repository;");
        $output->writeln("");
        $output->writeln("use App\\Model\\".$this->names['model_name'].";");
        $output->writeln("use Hyperf\\Di\\Annotation\\Inject;");
        $output->writeln("");

        $output->writeln("class ".$this->names['repository_name']." extends BaseRepository");
        $output->writeln("{");
        $output->writeln("    /**");
        $output->writeln("     * @Inject");
        $output->writeln("     * @var ". $this->names['model_name']);
        $output->writeln("     */");
        $output->writeln("    protected \$model;");
        $output->writeln("}");

        $this->line($this->names['repository_path'] . "已生成", 'info');
    }

    private function makeModel()
    {
        $output = new StreamOutput(fopen($this->names['model_path'], 'w+', false));
        $output->writeln("<?php");
        $output->writeln("/**");
        $output->writeln(" * This file is part of Hyperf Mall.");
        $output->writeln(" * ");
        $output->writeln(" * @link     https://gitee.com/scwlkj/hyperf_mall");
        $output->writeln(" * @contact  hyperf_mall@163.com");
        $output->writeln(" */");
        $output->writeln("");
        $output->writeln("declare(strict_types=1);");
        $output->writeln("");
        $output->writeln("namespace App\Model;");
        $output->writeln("");
        $output->writeln("class ".$this->names['model_name']." extends BaseModel{");
        $output->writeln("    protected \$fillable = [" );
        foreach ($this->names['filltable'] as $field){
            $output->writeln("        '{$field}'," );
        }
        $output->writeln("    ];" );
        $output->writeln("}");

        $this->line($this->names['model_path'] . "已生成", 'info');
    }
}
